%% Simulate Simple Shocks with Optimal Policy Models
% by Jaromir Benes
%
% Run three shock simulations: a demand shock, an anticipated future demand
% shock, and a cost-push shock, to illustrate the performance of the three
% versions of the model (a simple rule, discretionary policy, commitment
% policy). Simulate the shocks also with loss functions that only include
% inflation to show that monetary policy can be much more effective in
% accommodating demand shocks that in offsetting cost-push shocks.

%% Clear Workspace
%
% Clear workspace, close all graphics figures, clear command window, and
% check the IRIS version.

clear;
close all;
home;
irisrequired 20140319;
%#ok<*NOPTS>

%% Load Discretion and Commitment Model Objects
%
% Load all three model objects created previously in `read_model`.

load read_model.mat m1 m2 m3;

%% Simulate a demand shock
%
% Simulate a demand shocks <?demandShock?> starting from a steady-state
% database <?sstateDbase?>. We use the same input database for all three
% simulations. The input database `d` must be though based on either `m2`
% or `m3` to include also initial conditions for the Lagrange multipliers
% (needed in simulating the commitment model `m3`).

d = sstatedb(m2,1:40); %?sstateDbase?
d.e(1) = 1; %?demandShock?
d

s1 = simulate(m1,d,1:40,'dbOverlay=',true);
s2 = simulate(m2,d,1:40,'dbOverlay=',true);
s3 = simulate(m3,d,1:40,'dbOverlay=',true);

dbplot(s1 & s2 & s3,0:40,{'y','pi','r'},'tight=',true);

grfun.bottomlegend('Rule','Discretion','Commitment');

grfun.ftitle('Demand Shock');

% ...
%
% Simulate the same shock with the weight on output and interest rate in
% the loss function set to zero <?zeroWeight?> in the discretion and
% commitment policy models. Create two new model objects, `m2i` and `m3i`,
% based on the existing `m2` and `m3`, respectively, assign `lmb1` and
% `lmb2` zeros in both of them, solve the models with the new parameters
% <?resolve?> (this is needed whenever some of the model parameters
% change), and repeat the simulation as above. Use the option `'round=' 5`
% to round the results to the 5-th decimal place because the output gap and
% inflation series deviate from their steady state values only by rounding
% errors, and the graphs would be confusing (try remove the option to see
% what happens in the graphs).
%
% The graphs show that, in theoretical models with an aggregate demand
% equation and a Phillips curve, the central bank is able to perfectly
% accommodate demand shocks to keep inflation at the target if it chooses
% to do so.

m2i = m2;
m2i.lmb1 = 0; %?zeroWeight?
m2i.lmb2 = 0; %?zeroWeight?

m3i = m3;
m3i.lmb1 = 0; %?zeroWeight?
m3i.lmb2 = 0; %?zeroWeight?

m2i = solve(m2i); %?resolve?
m3i = solve(m3i); %?resolve?

s2i = simulate(m2i,d,1:40,'dbOverlay=',true);
s3i = simulate(m3i,d,1:40,'dbOverlay=',true);

dbplot(s2i & s3i,0:40,{'y','pi','r'}, ...
    'tight=',true,'round=',5); %?round?

grfun.bottomlegend('Discretion with Inflation in Loss Function Only', ...
    'Commitment with Inflation in Loss Function Only');

grfun.ftitle('Demand Shock with Only Inflation in Loss Function');

%% Simulate Anticipated Future Demand Shock
%
% Simulate a demand shock at a future date that is anticipated a number of
% periods in advance. Create an input database with the demand shock placed
% at a future time (t = 4) <?futureShock?>. Note that all future shocks are
% by default anticipated in `simulate` unless you change the option
% `'anticipate='`. When plotting the results, highlight the time range
% before the shock occurs using the option `'highlight='` <?highlight?>.

t = 4;

d = sstatedb(m2,1:40);
d.e(t) = 1; %?futureShock?

s1 = simulate(m1,d,1:40,'dbOverlay=',true);
s2 = simulate(m2,d,1:40,'dbOverlay=',true);
s3 = simulate(m3,d,1:40,'dbOverlay=',true);

dbplot(s1 & s2 & s3,0:40,{'y','pi','r'}, ...
    'tight=',true,'highlight=',0:t-1); %?highlight?

grfun.bottomlegend('Rule', ...
    'Discretion', ...
    'Commitment');

grfun.ftitle('Anticipated Future Demand Shock');

% ...
%
% The perfect accommodation argument made above also extends to anticipated
% future demand shocks. Simulate the future anticipated demand shock in the
% discretion and commitment models `m2i` and `m3i`, respectively, and note
% that neither the output gap nor inflation respond to a perfectly
% accommodated shock.

s2i = simulate(m2i,d,1:40,'dbOverlay=',true);
s3i = simulate(m3i,d,1:40,'dbOverlay=',true);

dbplot(s2i & s3i,0:40,{'y','pi','r'}, ...
    'tight=',true,'highlight=',0:t-1,'round=',5); %?highlight? %?round?

grfun.bottomlegend('Discretion with Inflation in Loss Function Only', ...
    'Commitment with Inflation in Loss Function Only');

grfun.ftitle(['Anticipated Future Demand Shock ', ...
    'with Only Inflation in Loss Function']);

%% Simulate a cost-push shock
%
% Finally, simulate a cost-push shock (shock to the Phillips curve). The
% simulation is designed the same way as the demand shocks above. Also,
% simulate the shock in the models that have only inflation in the loss
% function. 

d = sstatedb(m2,1:40);
d.u(1) = 1;

s1 = simulate(m1,d,1:40,'dbOverlay=',true);
s2 = simulate(m2,d,1:40,'dbOverlay=',true);
s3 = simulate(m3,d,1:40,'dbOverlay=',true);

dbplot(s1 & s2 & s3,0:40,{'y','pi','r'},'tight=',true);

grfun.bottomlegend('Rule', ...
    'Discretion', ...
    'Commitment');

grfun.ftitle('Cost-Push Shock');

% ...
%
% Simulate a cost-push shock in models with only inflation in the loss
% function, `m2i` and `m3i`. Whatever the preferences of the central bank,
% it cannot perfectly offset cost-push shocks: in response to such shocks,
% both inflation and the output gap will depart temporarily from their
% steady-state levels (i.e. the target and zero, respectively). The
% presence of cost-push shocks poses a trade-off to policymakers in these
% types of models.

s2i = simulate(m2i,d,1:40,'dbOverlay=',true);
s3i = simulate(m3i,d,1:40,'dbOverlay=',true);

dbplot(s2i & s3i,0:40,{'y','pi','r'}, ...
    'tight=',true,'round=',5); %?round?

grfun.bottomlegend('Discretion with Inflation in Loss Function Only', ...
    'Commitment with Only Inflation in Loss Function');

grfun.ftitle(['Cost-Push Shock ', ...
    'with Only Inflation in Loss Function']);

%% Help on IRIS Functions Used in This File
%
% Use either `help` to display help in the command window, or `idoc`
% to display help in an HTML browser window.
%
%    help model
%    help model/model
%    help model/subsasgn
%    help model/solve
%    help model/sstate
%    help model/sstatedb
%    help model/simulate
%    help dbase/dbplot
%    help grfun/bottomlegend
%    help grfun/ftitle
